﻿#include "FastFind.au3"
#include "ImageSearch.au3"

$win = "디아블로 III"

HotKeySet(",", "Toggle")
HotKeySet(".", "Stop")
HotKeySet("/", "PrintPixelColor")
HotKeySet("'", "loot")

Global $gameDelay = 1.0

Const $heroPos = [485, 310]

Const $pixelMenu = 2097920
Const $pixelInTown = 0x3D3F44
Const $pixelShop = 0xCE7B29
Const $pixelDeposit = 0xCE7B29

;---------------------------------------------------------------------------------
Const $PI = 3.14159265359

Opt("PixelCoordMode", 0)
Opt("MouseCoordMode", 0)

Enum $statusNone = 0, $statusMenu, $statusInTown, $statusShop, $statusDeposit, $statusDungeon, $statusBattle, $statusLoot, $statusDone

Global $hWnd = WinActivate($win)
Global $winPos = WinGetPos($hWnd)
$winPos[2] = 960
$winPos[3] = 600

FFSetWnd($hWnd, False)

Global $pause = False
Global $loopCount = 0

Global $state = $statusNone
Global $nextState = $statusNone
Global $hStateTimer = 0

Global $stateStep = 0
Global $hStateStepTimer = 0
Global $stateCheckTime = 0

WinMove($hWnd, "", $winPos[0], $winPos[1], $winPos[2], $winPos[3])
changeState($statusMenu)

While True
   Sleep(100)

   If ($pause = True) Then
	  ContinueLoop
   EndIf

   If WinActive($hWnd) = 0 Then
	  Sleep(1000)
	  WinActivate($hWnd)
   EndIf

   FFSnapShot(200, 0, 760, 500)

   Local $pixel = PixelGetColor(454, 315)
   If $pixel = 0xC1934C Then
	  MouseClick("left", 477, 394)
	  Sleep(3000)
	  changeState($statusMenu)
   EndIf

   If $state <> $statusNone And $state <> $statusMenu And $state <> $statusDone And TimerDiff($hStateTimer) > (45000 * $gameDelay) Then
	  changeState($statusDone)
   EndIf

   If $nextState <> $statusNone Then
	  checkStateChange()
	  ContinueLoop
   EndIf

   Switch $state
   Case $statusMenu
	  statusMenu()
   Case $statusInTown
	  statusInTown()
   Case $statusShop
	  statusShop()
   Case $statusDeposit
	  statusDeposit()
   Case $statusDungeon
	  statusDungeon()
   Case $statusBattle
	  statusBattle()
   Case $statusLoot
	  statusLoot()
   Case $statusDone
	  statusDone()
   EndSwitch
WEnd

Func changeState($newState, $newStep = 0)
   $nextState = $newState
   $hStateTimer = TimerInit()

   $stateStep = $newStep
EndFunc

Func checkStateChange()
   Switch $nextState
   Case $statusMenu
	  Local $pixel = PixelGetColor(505, 544)
	  If $pixel <> $pixelMenu Then
		 ToolTip("statusMenu : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  $loopCount += 1
	  ToolTip("statusMenu : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusInTown
	  Local $pixel = PixelGetColor(766, 593)
	  If $pixel <> $pixelInTown Then
		 ToolTip("statusInTown : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInTown : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusShop
	  Local $pixel = PixelGetColor(800, 71)
	  If $pixel <> $pixelShop Then
		 ToolTip("statusShop : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInShop : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDeposit
	  Local $pixel = PixelGetColor(800, 71)
	  If $pixel <> $pixelDeposit Then
		 ToolTip("statusDeposit : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInDeposit : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDungeon
	  ToolTip("statusDungeon : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusBattle
	  ToolTip("statusBattle : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusLoot
	  ToolTip("statusLoot : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDone
	  Local $pixel = PixelGetColor(790, 70)
	  If $pixel <> 0xB00639 Then
		 Send("{ESC}")
		 Sleep(500 * $gameDelay)
		 Return
	  EndIf

	  ToolTip("statusDone : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   EndSwitch

   $state = $nextState
   $nextState = $statusNone
   $hStateTimer = TimerInit()

   $hStateStepTimer = TimerInit()
   $stateCheckTime = 0
EndFunc

Func statusMenu()
   Sleep(500 * $gameDelay)
   MouseClick("left", 143, 347)
   Sleep(1000 * $gameDelay)
   MouseClick("left", 474, 401)
   Sleep(500 * $gameDelay)

   Local $posX=0, $posY=0
   Local $search = _ImageSearchArea('1.png', 1, $winPos[0], $winPos[1], $winPos[0]+$winPos[2], $winPos[1]+$winPos[3], $posX, $posY, 10)
   If $search = 1 Then
	  MouseClick('left', $posX-$winPos[0], $posY-$winPos[1])
	  Sleep(500 * $gameDelay)
   EndIf

   MouseWheel("down", 4)
   Sleep(500 * $gameDelay)

   $search = _ImageSearchArea('2.png', 1, $winPos[0], $winPos[1], $winPos[0]+$winPos[2], $winPos[1]+$winPos[3], $posX, $posY, 10)
   If $search = 1 Then
	  MouseClick('left', $posX-$winPos[0], $posY-$winPos[1])
	  Sleep(500 * $gameDelay)
   EndIf

   MouseClick("left", 421, 463)
   Sleep(500 * $gameDelay)

   Local $pixel = PixelGetColor(457, 258)
   If $pixel = 0xD28402 Then
	  MouseClick("left", 421, 392)
	  Sleep(500 * $gameDelay)
   EndIf

   MouseClick("left", 587, 512)
   Sleep(3000 * $gameDelay)

   changeState($statusInTown)
EndFunc

Func statusInTown()
   Sleep(500 * $gameDelay)

   Static Local $shopCount = 1
   If $shopCount = 9 Then
	  $shopCount = 1

	  MouseClick("left", 625, 134)
	  Sleep(1500 * $gameDelay)
	  MouseClick("left", 582, 161)

	  changeState($statusShop)
   Else
	  $shopCount += 1

	  Send("m")
	  Sleep(500 * $gameDelay)

	  MouseClick("left", 330, 466)
	  Sleep(1000 * $gameDelay)

	  changeState($statusDungeon)
   EndIf

EndFunc

Func statusShop()
   MouseClick("Left", 291, 373)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 154, 362)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 287, 297)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 150, 194)
   Sleep(300 * $gameDelay)

   Local $pixel = PixelGetColor(147, 195)
   If $pixel = 0xD9752F Then
	  MouseClick("left", 147, 195)
	  Sleep(300 * $gameDelay)
	  MouseClick("left", 418, 238)
	  Sleep(300 * $gameDelay)
   EndIf

   Local $pixel = PixelGetColor(184, 195)
   If $pixel = 0xC4802C Then
	  MouseClick("left", 184, 195)
	  Sleep(300 * $gameDelay)
	  MouseClick("left", 418, 238)
	  Sleep(300 * $gameDelay)
   EndIf

   Local $pixel = PixelGetColor(222, 195)
   If $pixel = 0xC4812C Then
	  MouseClick("left", 222, 195)
	  Sleep(300 * $gameDelay)
	  MouseClick("left", 418, 238)
	  Sleep(300 * $gameDelay)
   EndIf

   Send("{ESC}")
   Sleep(500 * $gameDelay)

   MouseClick("Left", 227, 482)
   Sleep(1500 * $gameDelay)
   MouseClick("Left", 165, 291)

   changeState($statusDeposit)
EndFunc

Func statusDeposit()
   For $slotNum = 0 To 4 Step 1
	  Local $tabPos[2] = [295, 180]
	  MouseClick("left", $tabPos[0], $tabPos[1] + $slotNum * 70)
	  Sleep(500 * $gameDelay)

	  Local $pixel = PixelGetColor(251, 420)
	  If $pixel = 0x130C08 Then
		 ExitLoop
	  EndIf
   Next

   Local $pos[2] = [678, 353]
   For $i = 0 To 5 Step 1
	  For $j = 0 To 9 Step 1
		 MouseClick("right", $pos[0] + $j * 28, $pos[1] + $i * 28, 1, 0)
		 Sleep(150 * $gameDelay)
	  Next
   Next

   Send("{ESC}")
   Sleep(500 * $gameDelay)

   Send("m")
   Sleep(500 * $gameDelay)

   MouseClick("left", 330, 466)

   changeState($statusDungeon)
EndFunc

Func statusDungeon()
   Switch $stateStep
   Case 0
	  Local $pixel = PixelGetColor(867, 146)
	  If $pixel = 0xF4C52E Then
		 Sleep(1000 * $gameDelay)
		 MouseClick("left", 831, 209, 2)
		 Sleep(2000 * $gameDelay)
		 $stateStep = 1
	  EndIf
   Case 1
	  moveAngle(325)
	  Local $pixel = PixelGetColor(570, 71)
	  If $pixel = 0x583813 Then
		 $stateStep = 2
		 $hStateStepTimer = TimerInit()
	  EndIf
   Case 2
	  moveAngle(325)
	  If (TimerDiff($hStateStepTimer) > 2000) Then
		 $stateStep = 3
		 $hStateStepTimer = TimerInit()
	  EndIf
   Case 3
	  Local $diffTime = TimerDiff($hStateTimer)
	  If $diffTime > $stateCheckTime + 500 Then
		 $stateCheckTime = TimerDiff($hStateTimer)

		 If (findEnemy() = True) Then
			Send("{SHIFTDOWN}")
			MouseDown("right")

			changeState($statusBattle)
			Return
		 EndIf

		 If (loot() = True) Then
			changeState($statusLoot)
			Return
		 EndIf
	  EndIf
   EndSwitch
EndFunc

Func moveAngle($angDeg)
   Local $angRad = $angDeg / 180 * $PI
   Local $x = 70 * Cos($angRad)
   Local $y = 70 * Sin($angRad)
   MouseMove($heroPos[0] + $x, $heroPos[1] + $y, 0)
   Send("w")
EndFunc

Func statusBattle()
   If (findEnemy() = True) Then
	  $stateCheckTime = TimerDiff($hStateTimer)
   EndIf

   Local $diffTime = TimerDiff($hStateTimer)
   If $diffTime > $stateCheckTime + 2000 Then
	  changeState($statusDungeon, 3)
	  MouseUp("right")
	  Send("{SHIFTUP}")
	  Return
   Else
	  Static Local $battleTimer1 = TimerInit()
	  If TimerDiff($battleTimer1) > 4500 Then
		 $battleTimer1 = TimerInit()
		 MouseClick("LEFT")
		 Sleep(100)
	  EndIf
	  Static Local $battleTimer2 = TimerInit()
	  If TimerDiff($battleTimer2) > 2500 Then
		 $battleTimer2 = TimerInit()
		 Send("1")
		 Sleep(100)
	  EndIf
	  Static Local $battleTimer3 = TimerInit()
	  If TimerDiff($battleTimer3) > 500 Then
		 $battleTimer3 = TimerInit()
		 Send("2")
		 Sleep(100)
	  EndIf
	  Static Local $battleTimer4 = TimerInit()
	  If TimerDiff($battleTimer4) > 500 Then
		 $battleTimer4 = TimerInit()
		 Send("3")
		 Sleep(100)
	  EndIf
	  Static Local $battleTimer5 = TimerInit()
	  If TimerDiff($battleTimer5) > 500 Then
		 $battleTimer5 = TimerInit()
		 Send("4")
		 Sleep(100)
	  EndIf
   EndIf
EndFunc

Func statusLoot()
   Send("`")

   If loot() = True Then
	  $stateCheckTime = TimerDiff($hStateTimer)
   EndIf

   MouseMove(250, 150, 0)

   Local $diffTime = TimerDiff($hStateTimer)
   If $diffTime > 5000 Or $diffTime > $stateCheckTime + 2000 Then
	  changeState($statusDone)
	  Return
   EndIf
EndFunc

Func findEnemy()
   FFResetExcludedAreas( )
   FFAddExcludedArea(390, 65, 565, 80)

   FFResetColors()
   FFAddColor(0xF70000)
   FFAddColor(0xF20000)
   FFAddColor(0xEC0000)
   FFAddColor(0xEA0000)
   FFAddColor(0xE80000)
   FFAddColor(0xD70000)

   Local $mousePos = MouseGetPos()
   Local $pos = FFNearestSpot(1, 1, $mousePos[0], $mousePos[1], -1, 0, False)
   If Not @error Then
	  ToolTip("FindEnemy", $winPos[0] + 100, $winPos[1] + 5)
	  MouseMove($pos[0], $pos[1] + 50)
	  Return True
   EndIf

   ToolTip("NotFindEnemy", $winPos[0] + 100, $winPos[1] + 5)
   ;FFSaveBMP("findEnemy")
   Return False
EndFunc

Func loot()
   FFResetExcludedAreas( )
   FFResetColors()
   FFAddColor(0x1C1008)
   FFAddColor(0x231008)
   FFAddColor(0x130A03)
   FFAddColor(0x291408)

   Local $pos = FFNearestSpot(1, 1, $heroPos[0], $heroPos[1], -1, 0, False)
   If Not @error Then
	  ToolTip("Loot", $winPos[0] + 100, $winPos[1] + 5)
	  MouseClick("left", $pos[0], $pos[1], 1, 0)

	  Local $x2 = ($heroPos[0] - $pos[0]) * ($heroPos[0] - $pos[0])
	  Local $y2 = ($heroPos[1] - $pos[1]) * ($heroPos[1] - $pos[1])

	  Local $dist = Sqrt($x2 + $y2)
	  Sleep((300 + (500 * $dist / 100))* $gameDelay )
	  Return True
   EndIf

   ToolTip("NotLoot", $winPos[0] + 100, $winPos[1] + 5)
   ;FFSaveBMP("loot")
   Return False
EndFunc

Func statusDone()
   MouseClick("left", 172, 298)
   Sleep(1000)

   MouseMove(100, 100)
   Sleep(5000)

   changeState($statusMenu)
EndFunc

Func Toggle()
   If $pause = True Then
	  $pause = False
	  ToolTip("Resume", $winPos[0] + 100, $winPos[1] + 5)
   Else
	  $pause = True
	  ToolTip("Pause : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)
   EndIf
EndFunc

Func Stop()
   ToolTip("Stop : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)
   Sleep(2000)
   Exit
EndFunc

Func PrintPixelColor()
   Local $pos = MouseGetPos()
   Local $color = PixelGetColor ($pos[0] , $pos[1])
   ToolTip($pos[0]&","&$pos[1]&":"&$color, $winPos[0] + 100, $winPos[1] + 5)
   Sleep(100000)
   Exit
EndFunc